#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include <sys/param.h>
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "esp_eth.h"
#include "nvs.h"
#include "esp_http_server.h"

#include <driver/gpio.h>

const char *TAG = "YEE-LIGHT";
// static const char *DEFAULT_AP_PASSWORD = "yee12345";

static uint8_t RUN_MODE = 0;
static char *SSID;
static char *PASS;
static uint32_t SSID_LEN = 0;
static uint32_t PASS_LEN = 0;

// uint32_t retry_count = 0;
// static const uint32_t max_retry_count = 100;

// static httpd_handle_t server = NULL;



// // "mac":"" MACSTR "" , MAC2STR(list[i].bssid)
// #define MAC2STR_4(a) (a)[4], (a)[5]
// #define MACSTR_4 "%02X%02X"
// #define MACSTR_UPPER "%02X-%02X-%02X-%02X-%02X-%02X"

// static httpd_handle_t start_webserver(void)
// {
//     httpd_handle_t server = NULL;
//     httpd_config_t config = HTTPD_DEFAULT_CONFIG();
//     config.max_uri_handlers = 16;

//     esp_err_t err = httpd_start(&server, &config);
//     // start web server
//     if (err == ESP_OK)
//     {
//         ESP_LOGI(TAG, "正在启动网络服务器, 侦听端口为：%d", config.server_port);
//         // register http router
//         httpd_register_uri_handler(server, &scan_wifi_list);
//         httpd_register_uri_handler(server, &set_wifi_config);
//         httpd_register_uri_handler(server, &restart);
//         httpd_register_uri_handler(server, &reset);
//         httpd_register_uri_handler(server, &power);
//         httpd_register_uri_handler(server, &change_mode);
//         httpd_register_uri_handler(server, &change_colour);
//         httpd_register_uri_handler(server, &change_colour_temperature);
//         httpd_register_uri_handler(server, &change_brightness);
//         return server;
//     }

//     ESP_LOGI(TAG, "网络服务器启动失败，失败原因：%d", err);
//     return NULL;
// }

// static void wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
// {
//     if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_AP_STACONNECTED)
//     {
//         wifi_event_ap_staconnected_t *event = (wifi_event_ap_staconnected_t *)event_data;
//         ESP_LOGI(TAG, "客户端加入，ID：%d，MAC地址：" MACSTR_UPPER "", event->aid, MAC2STR(event->mac));
//     }
//     else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_AP_STADISCONNECTED)
//     {
//         wifi_event_ap_stadisconnected_t *event = (wifi_event_ap_stadisconnected_t *)event_data;
//         ESP_LOGI(TAG, "客户端离开，ID：%d，MAC地址：" MACSTR_UPPER "", event->aid, MAC2STR(event->mac));
//     }
//     else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_AP_START)
//     {
//         ESP_LOGI(TAG, "软路由模式已启动，等待连接…………");
//     }
//     else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START)
//     {
//         esp_wifi_connect();
//     }
//     else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED)
//     {
//         ESP_LOGI(TAG, "设备离线，10秒后尝试重新连接");
//         vTaskDelay(10000 / portTICK_PERIOD_MS);

//         if (retry_count > max_retry_count)
//         {
//             ESP_LOGI(TAG, "设备离线，尝试次数过多，10秒后将清理WIFI配置，并重新启动进入配网模式");
//             vTaskDelay(10000 / portTICK_PERIOD_MS);
//             clear_wifi_nvs_data();
//             esp_restart();
//         }
//         ESP_LOGI(TAG, "设备离线，正在尝试第 %d 次重新连接", ++retry_count);
//         esp_wifi_connect();
//     }
//     else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_SCAN_DONE)
//     {
//         xEventGroupSetBits(wifi_event_group, SCAN_DONE_BIT);
//     }
// }

// static void ip_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
// {
//     if (IP_EVENT == event_base && IP_EVENT_STA_GOT_IP == event_id)
//     {
//         retry_count = 0;
//         ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
//         ESP_LOGI(TAG, "设备上线，自动分配IP地址：" IPSTR "", IP2STR(&event->ip_info.ip));
//     }
//     else if (IP_EVENT == event_base && IP_EVENT_AP_STAIPASSIGNED == event_id)
//     {
        
//     server = start_webserver();
//         if (NULL == event_data)
//         {
//             ESP_LOGI(TAG, "client ip empty");
//         }
//     }
// }

static void wifi_init_start(void)
{
//     // create event group
//     wifi_event_group = xEventGroupCreate();
//     // init tcp/ip protocol
//     tcpip_adapter_init();
//     ESP_ERROR_CHECK(esp_event_loop_create_default());

//     wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
//     // init wifi
//     ESP_ERROR_CHECK(esp_wifi_init(&cfg));
//     // register handler for every event of the base event WIFI_EVENT
//     ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL));
//     ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, &ip_event_handler, NULL));

//     // first start or hasn't wifi config
//     if (RUN_MODE == 0)
//     {
//         // get ap_if mac addr
//         uint8_t mac[6];
//         esp_wifi_get_mac(ESP_IF_WIFI_AP, mac);

//         // generate ssid. The last four hex word is mac address.
//         char ssid[15];
//         sprintf(&ssid[0], "YEE-LIGHT_" MACSTR_4 "", MAC2STR_4(mac));

//         // generate ap config
//         wifi_config_t wifi_ap_config = {
//             .ap = {
//                 .ssid_len = 14,
//                 .max_connection = 10,
//                 .authmode = WIFI_AUTH_WPA2_PSK},
//         };
//         // write customize wifi ssid
//         memcpy(wifi_ap_config.ap.ssid, ssid, 14);
//         // write default ap password
//         memcpy(wifi_ap_config.ap.password, DEFAULT_AP_PASSWORD, 8);
//         // set double mode ( ap + stasion)
//         ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_APSTA));
//         // set ap configure
//         ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_AP, &wifi_ap_config));
//         ESP_LOGI(TAG, "自动根据网卡物理地址生成AP：%s, 默认密码：%s", wifi_ap_config.ap.ssid, DEFAULT_AP_PASSWORD);
//     }

//     // generate wifi station config
//     wifi_config_t wifi_sta_config = {
//         .sta = {
//             .scan_method = WIFI_ALL_CHANNEL_SCAN,
//             .sort_method = WIFI_CONNECT_AP_BY_SIGNAL,
//             .threshold.rssi = -127},
//     };
//     // not first start and has config wifi info
//     if (RUN_MODE == 1)
//     {
//         // config wifi ssid
//         memcpy(wifi_sta_config.sta.ssid, SSID, SSID_LEN);
//         // config wifi password
//         memcpy(wifi_sta_config.sta.password, PASS, PASS_LEN);
//         // set station mode
//         ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
//     }
//     // set station configure
//     ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_sta_config));
//     // start wifi
//     ESP_ERROR_CHECK(esp_wifi_start());
}

void app_main(void)
{
    esp_reset_reason_t reason = esp_reset_reason();
    ESP_LOGI(TAG, "%d", reason);

    // init nvs
    esp_err_t err = nvs_flash_init();
    if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND)
    {
        // nvs no free space or has new version, clear nvs and retry init
        ESP_ERROR_CHECK(nvs_flash_erase());
        ESP_ERROR_CHECK(nvs_flash_init());
    }

    // read wifi config info from nvs
    nvs_handle_t wifi_config_handle;
    err = nvs_open("YEE_WIFI_CONF", NVS_READONLY, &wifi_config_handle);

    if (err == ESP_OK)
    {
        size_t total = 0;
        err = nvs_get_used_entry_count(wifi_config_handle, &total);

        if (err == ESP_OK && total == 6)
        {
            // get ssid length and password length
            ESP_ERROR_CHECK(nvs_get_u32(wifi_config_handle, "SSID_LEN", &SSID_LEN));
            ESP_ERROR_CHECK(nvs_get_u32(wifi_config_handle, "PASS_LEN", &PASS_LEN));

            SSID = malloc(SSID_LEN);
            PASS = malloc(PASS_LEN);

            ESP_ERROR_CHECK(nvs_get_str(wifi_config_handle, "WIFI_SSID", SSID, &SSID_LEN));
            ESP_ERROR_CHECK(nvs_get_str(wifi_config_handle, "WIFI_PASS", PASS, &PASS_LEN));

            nvs_close(wifi_config_handle);
            RUN_MODE = 1;
            ESP_LOGI(TAG, "系统启动，获取到网络配置信息，进入工作模式");
        }
        else
        {
            RUN_MODE = 0;
            ESP_LOGI(TAG, "系统启动，未检测到配置信息，自动进入配网模式");
        }
    }
    else
    {
        //not found config info, set ap mode, configure wifi net
        RUN_MODE = 0;
        ESP_LOGI(TAG, "系统启动，未检测到配置信息，自动进入配网模式");
    }
    wifi_init_start();
    // vTaskDelay(3000 / portTICK_PERIOD_MS);
    // esp_restart();
}

class 